package com.leonzhangxf;

import com.leonzhangxf.server.ProviderService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author leonzhangxf
 */
@SpringBootApplication
public class ConsumerApp implements ApplicationRunner {

    public static void main(String[] args) {
        new SpringApplicationBuilder(ConsumerApp.class).run(args);
    }

    private ProviderService providerService;

    private ThreadPoolExecutor executorService =
        new ThreadPoolExecutor(10, 40,
            60, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(2000));

    @Override
    public void run(ApplicationArguments args) throws Exception {
        CountDownLatch countDownLatch = new CountDownLatch(2000);
        for (int j = 0; j < 2000; j++) {
            executorService.submit(() -> {
                try {
                    int i = ThreadLocalRandom.current().nextInt(3);
                    switch (i) {
                        case 0:
                            providerService.methodA("call a");
                            break;
                        case 1:
                            providerService.methodB("call b");
                            break;
                        case 2:
                            providerService.methodC("call c");
                            break;
                        default:
                            System.out.println("no invoke");
                    }
                } finally {
                    countDownLatch.countDown();
                }
            });
        }
        countDownLatch.await();
    }

    @Reference
    public void setProviderService(ProviderService providerService) {
        this.providerService = providerService;
    }
}
